﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
// std headers

// qt headers
#include <QLineEdit>
#include <QLabel>
#include <QFormLayout>
#include <QPushButton>
#include <QEvent>
#include <QKeyEvent>

// gcmp headers

// custom headers
#include "SpecificationAddingDialog.h"
#include "TranslatorManager.h"
#include "GbmpNew.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 
namespace gmepgcs
{
    SpecificationAddingDialog::SpecificationAddingDialog(QWidget *parent, Qt::WindowFlags flags) :
        MessageDialog(parent, flags),
        m_vExistedSpecifications(),
        m_currentSpecification(),
        m_specificationNameIsValid(false),
        m_isConfirmable(false),
        m_addedSpecification(),
        m_errorMessage(),
        m_pLeSpecificationName(nullptr),
        m_pLblSpecificationNameValidationTip(nullptr),
        m_btnOk(nullptr),
        m_specificationNameLineEditNormalStyle(),
        m_specificationNameLineEditErrorStyle()
    {
        Init();
    }

    SpecificationAddingDialog::~SpecificationAddingDialog()
    {

    }

    SpecificationAddingDialog *SpecificationAddingDialog::s_pInstance = nullptr;
    SpecificationAddingDialog * SpecificationAddingDialog::Get(QWidget * parent)
    {
        if (!SpecificationAddingDialog::s_pInstance)
        {
            SpecificationAddingDialog::s_pInstance = NEW_AS_QT(SpecificationAddingDialog,parent);
            SpecificationAddingDialog::s_pInstance->setObjectName("SpecificationAddingDialog");
        }
        else if (SpecificationAddingDialog::s_pInstance->parentWidget() != parent)
        {
            SpecificationAddingDialog::s_pInstance->deleteLater();
            SpecificationAddingDialog::s_pInstance = NEW_AS_QT(SpecificationAddingDialog,parent);
            SpecificationAddingDialog::s_pInstance->setObjectName("SpecificationAddingDialog");
        }
        return SpecificationAddingDialog::s_pInstance;
    }

    MessageDialog::MessageDialogResult SpecificationAddingDialog::Show(const std::vector<std::wstring>& existedSpecifications, const std::wstring & currentSpecification, std::wstring & addedSpecification, QWidget * parent)
    {
        SpecificationAddingDialog *pDialog = SpecificationAddingDialog::Get(parent);
        if (!pDialog)
        {
            return SpecificationAddingDialog::MessageDialogResult::ResultNotSet;
        }

        pDialog->Resume();
        pDialog->m_vExistedSpecifications = existedSpecifications;
        pDialog->m_currentSpecification = currentSpecification;

        pDialog->Show();

        pDialog->setModal(true);
        pDialog->exec();

        MessageDialog::MessageDialogResult result = pDialog->GetDialogResult();
        addedSpecification = pDialog->GetAddedSpecification();

        return result;
    }

    bool SpecificationAddingDialog::eventFilter(QObject * obj, QEvent * event)
    {
        if (nullptr != event && event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
            if (keyEvent && (keyEvent->key() == Qt::Key_Return))
            {
                QLineEdit *pLineEdit = dynamic_cast<QLineEdit*>(obj);
                if (pLineEdit && (pLineEdit == m_pLeSpecificationName))
                {
                    DBG_WARN_AND_RETURN_FALSE_UNLESS(m_btnOk, L"m_btnOk为空", L"GMEP", L"2024-01-30");
                    m_btnOk->click();
                    return true;
                }
            }
        }

        return QWidget::eventFilter(obj, event);
    }

    void SpecificationAddingDialog::Init()
    {
        // specification name caption
        QLabel *pLblSpecificationNameCaption = NEW_AS_QT( QLabel,QString::fromStdWString(GBMP_TR(L"名称")));
        DBG_WARN_AND_RETURN_VOID_UNLESS(pLblSpecificationNameCaption, L"pLblSpecificationNameCaption为空", L"GMEP", L"2024-01-30");
        pLblSpecificationNameCaption->setStyleSheet(
            "QLabel{"
            "font-family:\"Microsoft YaHei\";"
            "font-size:12px;"
            "color:rgba(40, 40, 51, 255);"
            "}"
        );

        // specification name line edit
        m_specificationNameLineEditNormalStyle =
            "QLineEdit{"
            "font-family:\"Microsoft YaHei\";"
            "font-size:12px;"
            "color:rgba(40, 40, 51, 255);"
            "border:1px solid rgba(189, 199, 213, 255);"
            "}";
        m_specificationNameLineEditErrorStyle =
            "QLineEdit{"
            "font-family:\"Microsoft YaHei\";"
            "font-size:12px;"
            "color:rgba(40, 40, 51, 255);"
            "border:1px solid rgba(255, 0, 0, 255);"
            "}";
        m_pLeSpecificationName = NEW_AS_QT(QLineEdit);
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLeSpecificationName, L"m_pLeSpecificationName为空", L"GMEP", L"2024-01-30");
        m_pLeSpecificationName->setObjectName("SpecificationLineEdit");
        m_pLeSpecificationName->installEventFilter(this);
        m_pLeSpecificationName->setFixedHeight(32);
        m_pLeSpecificationName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        m_pLeSpecificationName->setPlaceholderText(QString::fromStdWString(GBMP_TR(L"请输入类型名称")));
        m_pLeSpecificationName->setStyleSheet(m_specificationNameLineEditNormalStyle);
        connect(m_pLeSpecificationName, &QLineEdit::textChanged, [=](const QString &) {ValidateSpecificationName(); });

        // specification name validation error tip label
        m_pLblSpecificationNameValidationTip = NEW_AS_QT(QLabel);
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLblSpecificationNameValidationTip, L"m_pLblSpecificationNameValidationTip为空", L"GMEP", L"2024-01-30");
        m_pLblSpecificationNameValidationTip->setContentsMargins(0, 0, 0, 0);
        m_pLblSpecificationNameValidationTip->setStyleSheet(
            "QLabel{"
            "font-family:\"Microsoft YaHei\";"
            "font-size:11px;"
            "color:rgba(255, 0, 0, 255);"
            "}"
        );

        // form layout
        QFormLayout *pFormLayout = NEW_AS_QT(QFormLayout);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pFormLayout, L"pFormLayout为空", L"GMEP", L"2024-01-30");
        pFormLayout->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
        pFormLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter);
        pFormLayout->setContentsMargins(0, 0, 0, 0);
        pFormLayout->setHorizontalSpacing(8);
        pFormLayout->setVerticalSpacing(0);
        pFormLayout->addRow(pLblSpecificationNameCaption, m_pLeSpecificationName);
        pFormLayout->addRow("", m_pLblSpecificationNameValidationTip);
        pFormLayout->setAlignment(m_pLblSpecificationNameValidationTip, Qt::AlignLeft | Qt::AlignTop);

        // central widget
        QWidget *pCentralWidget = NEW_AS_QT(QWidget);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pCentralWidget, L"pCentralWidget为空", L"GMEP", L"2024-01-30");
        pCentralWidget->setObjectName("CentralWidget");
        pCentralWidget->setLayout(pFormLayout);
        SetCentralWidget(pCentralWidget);

        // dialog self
        setFixedWidth(320);
        setMinimumHeight(152);
        setWindowIcon(QIcon());
        setWindowTitle(QString::fromStdWString(GBMP_TR(L"新建类型")));
        SetButtons(MessageDialogButton::BtnCancel | MessageDialogButton::BtnOk);
        SetCentralWidgetMargin(QMargins(16, 16, 16, 8));

        m_btnOk = GetButton(MessageDialogButton::BtnOk);
    }

    void SpecificationAddingDialog::Resume()
    {
        m_vExistedSpecifications = std::vector<std::wstring>();
        m_currentSpecification.clear();
        m_specificationNameIsValid = false;
        m_isConfirmable = false;
        m_addedSpecification.clear();
        m_errorMessage.clear();

        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLeSpecificationName, L"m_pLeSpecificationName为空", L"GMEP", L"2024-01-30");
        m_pLeSpecificationName->clear();
        m_pLeSpecificationName->setStyleSheet(m_specificationNameLineEditNormalStyle);
        m_pLeSpecificationName->setFocus();

        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLblSpecificationNameValidationTip, L"m_pLblSpecificationNameValidationTip为空", L"GMEP", L"2024-01-30");
        m_pLblSpecificationNameValidationTip->setText("");
        //m_pLblSpecificationNameValidationTip->setVisible(false);

        if (m_btnOk)
        {
            m_btnOk->setEnabled(false);
        }
    }

    void SpecificationAddingDialog::Show()
    {
        m_addedSpecification = m_currentSpecification + GBMP_TR(L"_新建");
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLeSpecificationName, L"m_pLeSpecificationName为空", L"GMEP", L"2024-01-30");
        m_pLeSpecificationName->setText(QString::fromStdWString(m_addedSpecification));
    }

    std::wstring SpecificationAddingDialog::GetAddedSpecification()
    {
        if (!m_isConfirmable)
        {
            return std::wstring();
        }

        return m_addedSpecification;
    }

    void SpecificationAddingDialog::ValidateSpecificationName()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLeSpecificationName, L"m_pLeSpecificationName为空", L"GMEP", L"2024-01-30");
        m_addedSpecification = m_pLeSpecificationName->text().trimmed().toStdWString();
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pLblSpecificationNameValidationTip, L"m_pLblSpecificationNameValidationTip为空", L"GMEP", L"2024-01-30");
        if (m_pLeSpecificationName->text().length() == 0)
        {
            m_pLeSpecificationName->setStyleSheet(m_specificationNameLineEditNormalStyle);
            m_pLblSpecificationNameValidationTip->setText(QString::fromStdWString(GBMP_TR(L"")));
            //m_pLblSpecificationNameValidationTip->setVisible(false);
            m_specificationNameIsValid = false;
            CheckConfirmable();
            return;
        }

        if (m_addedSpecification.length() == 0)
        {
            m_pLeSpecificationName->setStyleSheet(m_specificationNameLineEditErrorStyle);
            m_pLblSpecificationNameValidationTip->setText(QString::fromStdWString(GBMP_TR(L"类型名称不能为空白")));
            //m_pLblSpecificationNameValidationTip->setVisible(true);
            m_specificationNameIsValid = false;
            CheckConfirmable();
            return;
        }

        auto foundSpecificationIterator = std::find(
            m_vExistedSpecifications.begin(),
            m_vExistedSpecifications.end(),
            m_addedSpecification);
        if (foundSpecificationIterator != m_vExistedSpecifications.end())
        {
            m_pLeSpecificationName->setStyleSheet(m_specificationNameLineEditErrorStyle);
            m_pLblSpecificationNameValidationTip->setText(QString::fromStdWString(GBMP_TR(L"该类型名称已存在")));
            //m_pLblSpecificationNameValidationTip->setVisible(true);
            m_specificationNameIsValid = false;
            CheckConfirmable();
            return;
        }


        m_pLeSpecificationName->setStyleSheet(m_specificationNameLineEditNormalStyle);
        m_pLblSpecificationNameValidationTip->setText(QString::fromStdWString(GBMP_TR(L"")));
        //m_pLblSpecificationNameValidationTip->setVisible(false);
        m_specificationNameIsValid = true;
        CheckConfirmable();
    }

    void SpecificationAddingDialog::CheckConfirmable()
    {
        m_isConfirmable = m_specificationNameIsValid;
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_btnOk, L"m_btnOk为空", L"GMEP", L"2024-01-30");
        m_btnOk->setEnabled(m_isConfirmable);
    }

}